/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"

#include "底层绘图/底层绘图框架.h"

#include "底层绘图/intern/Vulkan/buffer/Vk图像.h"
#include "底层绘图/intern/Vulkan/Vulkan框架.h"

#include "底层绘图/intern/Vulkan/线管/线管.h"
#include "底层绘图/intern/Vulkan/线管/着色器.h"

#include "物体/S_摄像机.h"
#include "物体/物体.h"
#include "面/面.h"



void f_ob_render_begin(S_设备环境& ctx, S_摄像机& 摄像机, C_场景渲染环境& 管线槽) {
	auto* rf = f_vk_get绘图框架(ctx);
	auto* rt = f_vk_get绘图环境(ctx);


	VkWriteDescriptorSet writes[6] = {};

	writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[0].pNext = nullptr;
	writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
	writes[0].dstArrayElement = 0;
	writes[0].dstSet = f_VkDescriptorSet(管线槽.m_管线参数设置_VS_Proj, 0);
	writes[0].descriptorCount = 1;
	writes[0].pBufferInfo = &f_vk_get缓存信息(摄像机.m_投影矩阵);
	writes[0].dstBinding = DEF_BINDING_PROJECT;

	writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
	writes[1].pNext = nullptr;
	writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
	writes[1].dstArrayElement = 0;
	writes[1].dstSet = f_VkDescriptorSet(管线槽.m_管线参数设置_VS_Mat4, 0);
	writes[1].descriptorCount = 1;
	writes[1].pBufferInfo = &f_vk_get缓存信息(ctx.m_几何图形->m_3DGPU缓存_变换);
	writes[1].dstBinding = DEF_binding_L1_3D_Tranform;



	vkUpdateDescriptorSets(rt->m_设备, 2, writes, 0, nullptr);

}

void f_ob_render_view(S_设备环境& ctx, const S_Viewport& 视口, const S_Rect2D& 裁剪, vec2* offset) {
	auto* rf = f_vk_get绘图框架(ctx);
	auto* rt = f_vk_get绘图环境(ctx);

	auto vert = static_cast<S_VkArray缓存*>(ctx.m_几何图形->m_3DGPU缓存_顶点);
	auto index = static_cast<S_VkArray缓存*>(ctx.m_几何图形->m_3DGPU缓存_索引);

	static VkDeviceSize fuck{};
	vkCmdBindVertexBuffers(rt->m_命令缓存, 0, 1, &(vert->m_Data.m_Buf), &fuck);
	vkCmdBindIndexBuffer(rt->m_命令缓存, index->m_Data.m_Buf, 0, VK_INDEX_TYPE_UINT32);

	vkCmdSetViewport(rt->m_命令缓存, 0, 1, (VkViewport*)&视口);
	vkCmdSetScissor(rt->m_命令缓存, 0, 1, (VkRect2D*)&裁剪);


	VkSampleLocationsInfoEXT sampleLocationsInfo = {};
	sampleLocationsInfo.sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT;
	sampleLocationsInfo.sampleLocationsPerPixel = VK_SAMPLE_COUNT_4_BIT;
	sampleLocationsInfo.sampleLocationGridSize = {1, 1}; // 网格大小
	sampleLocationsInfo.sampleLocationsCount = 4;
	if (offset) {
		sampleLocationsInfo.pSampleLocations = (VkSampleLocationEXT*)offset;
		//vkCmdSetSampleLocations()
	}
	else {
		static VkSampleLocationEXT location{};
		sampleLocationsInfo.pSampleLocations = &location;
	}
	rf->vkCmdSetSampleLocationsEXT(rt->m_命令缓存, &sampleLocationsInfo);
}



void f_ob_render(S_物体* ob, E_管线槽 管线槽, uint32 fb) {
	if (!ob->m_显示) return;
	uint32 loc = 0;

	for (auto& e : ob->m_网格模型) {
		
		if( ((1<<loc) & fb) ) {
			e.m_Mesh->mf_参数设置回调(ob, e, loc);
			f_me_render(e, e.m_多维材质槽[0], 管线槽, e.m_深度偏移);
		}

		++loc;
	}
}

void f_ob_render(S_物体* ob, uint32 材质ID) {
	if (!ob->m_显示) return;

	auto& e = ob->m_网格模型.front();
	e.m_Mesh->mf_参数设置回调(ob, e, 0);
	f_me_render(e, e.m_多维材质槽[材质ID], E_管线槽::e_颜色渲染, ob->m_深度偏移);
}

void f_ob_render_s(S_物体* ob, E_管线槽 管线槽, uint32 loc) {
	auto& e = ob->m_网格模型[loc];

	e.m_Mesh->mf_参数设置回调(ob, e, loc);
	f_me_render(e, e.m_多维材质槽[0], 管线槽, e.m_深度偏移);
}





